home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 4 / QRZ Ham Radio Callsign Database - Volume 4.iso / files / tcpip / amiga / asrc29p.lha / tcpcmd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-29  |  8.0 KB  |  362 lines

  1. #include <stdio.h>
  2. #include "global.h"
  3. #include "timer.h"
  4. #include "mbuf.h"
  5. #include "netuser.h"
  6. #include "internet.h"
  7. #include "tcp.h"
  8. #include "cmdparse.h"
  9. #include "commands.h"
  10.  
  11. static int doirtt __ARGS((int argc,char *argv[],void *p));
  12. static int domss __ARGS((int argc,char *argv[],void *p));
  13. static int dortt __ARGS((int argc,char *argv[],void *p));
  14. static int dotcpkick __ARGS((int argc,char *argv[],void *p));
  15. static int dotcpreset __ARGS((int argc,char *argv[],void *p));
  16. static int dotcpretry __ARGS((int argc,char *argv[],void *p));
  17. static int dotcpstat __ARGS((int argc,char *argv[],void *p));
  18. static int dotcptimer __ARGS((int argc,char *argv[],void *p));
  19. static int dotcptr __ARGS((int argc,char *argv[],void *p));
  20. static int dowindow __ARGS((int argc,char *argv[],void *p));
  21. static int dotcpblimit __ARGS((int argc,char *argv[],void *p));
  22. static int tstat __ARGS((int flagit));
  23.  
  24. /* TCP subcommand table */
  25. static struct cmds Tcpcmds[] = {
  26.     "blimit",    dotcpblimit,    0, 0,    NULLCHAR,
  27.     "fullstat",    dotcpstat,    0, 0,    NULLCHAR,
  28.     "irtt",        doirtt,        0, 0,    NULLCHAR,
  29.     "kick",        dotcpkick,    0, 2,    "tcp kick <tcb>",
  30.     "mss",        domss,        0, 0,    NULLCHAR,
  31.     "reset",    dotcpreset,    0, 2,    "tcp reset <tcb>",
  32.     "retry",    dotcpretry,    0, 0,    NULLCHAR,
  33.     "rtt",        dortt,        0, 3,    "tcp rtt <tcb> <val>",
  34.     "status",    dotcpstat,    0, 0,    NULLCHAR,
  35.     "timertype",    dotcptimer,    0, 0,    NULLCHAR,
  36.     "trace",    dotcptr,    0, 0,    NULLCHAR,
  37.     "window",    dowindow,    0, 0,    NULLCHAR,
  38.     NULLCHAR,
  39. };
  40.  
  41. int dotcp(argc,argv,p)
  42. int argc;
  43. char *argv[];
  44. void *p;
  45. {
  46.     if(argc == 1)
  47.         return dotcpstat(argc,argv,p);
  48.     return subcmd(Tcpcmds,argc,argv,p);
  49. }
  50.  
  51. static int dotcptr(argc,argv,p)
  52. int argc;
  53. char *argv[];
  54. void *p;
  55. {
  56.     return setbool(&Tcp_trace,"TCP state tracing",argc,argv);
  57. }
  58.  
  59. /* Eliminate a TCP connection */
  60. static int dotcpreset(argc,argv,p)
  61. int argc;
  62. char *argv[];
  63. void *p;
  64. {
  65.     register struct tcb *tcb;
  66.  
  67.     tcb = (struct tcb *)ltop(htol(argv[1]));
  68.     if(!tcpval(tcb)){
  69.         tprintf(Notval);
  70.         return 1;
  71.     }
  72.     close_self(tcb,RESET);
  73.     return 0;
  74. }
  75.  
  76. /* Set initial round trip time for new connections */
  77. static int doirtt(argc,argv,p)
  78. int argc;
  79. char *argv[];
  80. void *p;
  81. {
  82.     struct tcp_rtt *tp;
  83.  
  84.     setlong(&Tcp_irtt,"TCP default irtt",argc,argv);
  85.     if(argc < 2){
  86.         for(tp = &Tcp_rtt[0];tp < &Tcp_rtt[RTTCACHE];tp++){
  87.             if(tp->addr != 0){
  88.                 if(tprintf("%s: srtt %lu mdev %lu\n",
  89.                  inet_ntoa(tp->addr),
  90.                  tp->srtt,tp->mdev) == EOF)
  91.                     break;
  92.             }
  93.         }
  94.     }
  95.     return 0;
  96. }
  97.  
  98. /* Set maximum number of backoffs before resetting the connection  wg7j wnos4 -oz1dti */
  99. static int dotcpretry(argc,argv,p)
  100. int argc;
  101. char *argv[];
  102. void *p;
  103. {
  104.     return setlong(&Tcp_retry,"TCP retry limit",argc,argv);
  105. }
  106.  
  107. /* Set smoothed round trip time for specified TCB */
  108. static int dortt(argc,argv,p)
  109. int argc;
  110. char *argv[];
  111. void *p;
  112. {
  113.     register struct tcb *tcb;
  114.  
  115.     tcb = (struct tcb *)ltop(htol(argv[1]));
  116.     if(!tcpval(tcb)){
  117.         tprintf(Notval);
  118.         return 1;
  119.     }
  120.     tcb->srtt = atol(argv[2]);
  121.     return 0;
  122. }
  123.  
  124. /* Force a retransmission */
  125. static int dotcpkick(argc,argv,p)
  126. int argc;
  127. char *argv[];
  128. void *p;
  129. {
  130.     register struct tcb *tcb;
  131.  
  132.     tcb = (struct tcb *)ltop(htol(argv[1]));
  133.     if(kick_tcp(tcb) == -1){
  134.         tprintf(Notval);
  135.         return 1;
  136.     }
  137.     return 0;
  138. }
  139.  
  140. /* Set default maximum segment size */
  141. static int domss(argc,argv,p)
  142. int argc;
  143. char *argv[];
  144. void *p;
  145. {
  146.     return setshort(&Tcp_mss,"TCP MSS",argc,argv);
  147. }
  148.  
  149. /* Set default window size */
  150. static int dowindow(argc,argv,p)
  151. int argc;
  152. char *argv[];
  153. void *p;
  154. {
  155.     return setshort(&Tcp_window,"TCP window",argc,argv);    
  156. }
  157.  
  158. /* Display status of TCBs */
  159. static int dotcpstat(argc,argv,p)
  160. int argc;
  161. char *argv[];
  162. void *p;
  163. {
  164.     register struct tcb *tcb;
  165.  
  166.     if(argc < 2){
  167.         if(strncmp(argv[0],"f",1))
  168.             tstat(0);
  169.         else
  170.             tstat(1);
  171.     } else {
  172.         tcb = (struct tcb *)ltop(htol(argv[1]));
  173.         if(tcpval(tcb))
  174.             st_tcp(tcb);
  175.         else
  176.             tprintf(Notval);
  177.     }
  178.     return 0;
  179. }
  180. extern int Tcp_blimit;
  181.  
  182. /* Set backoff limit on the connection; from N1BEE */
  183. static int dotcpblimit(argc,argv,p)
  184. int argc;
  185. char *argv[];
  186. void *p;
  187. {
  188.     return setint(&Tcp_blimit,"backoff limit",argc,argv);
  189. }
  190.  
  191. /* Dump TCP stats and summary of all TCBs
  192. /*     &TCB Rcv-Q Snd-Q  Local socket           Remote socket          State
  193.  *     1234     0     0  xxx.xxx.xxx.xxx:xxxxx  xxx.xxx.xxx.xxx:xxxxx  Established
  194.  */
  195. static int tstat(flagit)
  196. int flagit;
  197. {
  198.     register int i;
  199.     register struct tcb *tcb;
  200.     int j;
  201.  
  202.     for(j=i=1;i<=NUMTCPMIB;i++){
  203.         if(Tcp_mib[i].name == NULLCHAR)
  204.             continue;
  205.         if((Tcp_mib[i].value.integer == 0) && (flagit == 0))
  206.             continue;
  207.         tprintf("(%2u)%-20s%10lu",i,Tcp_mib[i].name,
  208.          Tcp_mib[i].value.integer);
  209.         if(j++ % 2)
  210.             tprintf("     ");
  211.         else
  212.             tprintf("\n");
  213.     }
  214.     if((j % 2) == 0)
  215.         tprintf("\n");
  216.  
  217.     tprintf("    &TCB Rcv-Q Snd-Q  Local socket           Remote socket          State\n");
  218.     for(i=0;i<NTCB;i++){
  219.         for(tcb=Tcbs[i];tcb != NULLTCB;tcb = tcb->next){
  220.             if((tcb->state == TCP_LISTEN) && (flagit == 0))
  221.                 continue;
  222.             tprintf("%8lx%6u%6u  ",ptol(tcb),tcb->rcvcnt,tcb->sndcnt);
  223.             tprintf("%-23s",pinet(&tcb->conn.local));
  224.             tprintf("%-23s",pinet(&tcb->conn.remote));
  225.             tprintf("%-s",Tcpstates[tcb->state]);
  226.             if(tcb->state == TCP_LISTEN && tcb->flags.clone)
  227.                 tprintf(" (S)");
  228.             if(tprintf("\n") == EOF)
  229.                 return 0;
  230.         }
  231.     }
  232.     return 0;
  233. }
  234.  
  235. /* Dump a TCP control block in detail */
  236. void st_tcp(tcb)
  237. struct tcb *tcb;
  238. {
  239.     int32 sent,recvd;
  240.  
  241.     if(tcb == NULLTCB)
  242.         return;
  243.     /* Compute total data sent and received; take out SYN and FIN */
  244.     sent = tcb->snd.una - tcb->iss;    /* Acknowledged data only */
  245.     recvd = tcb->rcv.nxt - tcb->irs;
  246.     switch(tcb->state){
  247.     case TCP_LISTEN:
  248.     case TCP_SYN_SENT:    /* Nothing received or acked yet */
  249.         sent = recvd = 0;    
  250.         break;
  251.     case TCP_SYN_RECEIVED:
  252.         recvd--;    /* Got SYN, no data acked yet */
  253.         sent = 0;
  254.         break;
  255.     case TCP_ESTABLISHED:    /* Got and sent SYN */
  256.     case TCP_FINWAIT1:    /* FIN not acked yet */
  257.         sent--;
  258.         recvd--;
  259.         break;
  260.     case TCP_FINWAIT2:    /* Our SYN and FIN both acked */
  261.         sent -= 2;
  262.         recvd--;
  263.         break;
  264.     case TCP_CLOSE_WAIT:    /* Got SYN and FIN, our FIN not yet acked */
  265.     case TCP_CLOSING:
  266.     case TCP_LAST_ACK:
  267.         sent--;
  268.         recvd -= 2;
  269.         break;
  270.     case TCP_TIME_WAIT:    /* Sent and received SYN/FIN, all acked */
  271.         sent -= 2;
  272.         recvd -= 2;
  273.         break;
  274.     }
  275.     tprintf("Local: %s",pinet(&tcb->conn.local));
  276.     tprintf(" Remote: %s",pinet(&tcb->conn.remote));
  277.     tprintf(" State: %s\n",Tcpstates[tcb->state]);
  278.     tprintf("      Init seq    Unack     Next Resent CWind Thrsh  Wind  MSS Queue      Total\n");
  279.     tprintf("Send:");
  280.     tprintf("%9lx",tcb->iss);
  281.     tprintf("%9lx",tcb->snd.una);
  282.     tprintf("%9lx",tcb->snd.nxt);
  283.     tprintf("%7lu",tcb->resent);
  284.     tprintf("%6u",tcb->cwind);
  285.     tprintf("%6u",tcb->ssthresh);
  286.     tprintf("%6u",tcb->snd.wnd);
  287.     tprintf("%5u",tcb->mss);
  288.     tprintf("%6u",tcb->sndcnt);
  289.     tprintf("%11lu\n",sent);
  290.  
  291.     tprintf("Recv:");
  292.     tprintf("%9lx",tcb->irs);
  293.     tprintf("         ");
  294.     tprintf("%9lx",tcb->rcv.nxt);
  295.     tprintf("%7lu",tcb->rerecv);
  296.     tprintf("      ");
  297.     tprintf("      ");
  298.     tprintf("%6u",tcb->rcv.wnd);
  299.     tprintf("     ");
  300.     tprintf("%6u",tcb->rcvcnt);
  301.     tprintf("%11lu\n",recvd);
  302.  
  303.     if(tcb->reseq != (struct reseq *)NULL){
  304.         register struct reseq *rp;
  305.  
  306.         tprintf("Reassembly queue:\n");
  307.         for(rp = tcb->reseq;rp != (struct reseq *)NULL; rp = rp->next){
  308.             if(tprintf("  seq x%lx %u bytes\n",
  309.              rp->seg.seq,rp->length) == EOF)
  310.                 return;
  311.         }
  312.     }
  313.     if(tcb->backoff > 0)
  314.         tprintf("Backoff %u ",tcb->backoff);
  315.     if(tcb->flags.retran)
  316.         tprintf("Retrying ");
  317.     switch(tcb->timer.state){
  318.     case TIMER_STOP:
  319.         tprintf("Timer stopped ");
  320.         break;
  321.     case TIMER_RUN:
  322.         tprintf("Timer running (%ld/%ld ms) ",
  323.          (long)MSPTICK * read_timer(&tcb->timer),
  324.          (long)MSPTICK * dur_timer(&tcb->timer));
  325.         break;
  326.     case TIMER_EXPIRE:
  327.         tprintf("Timer expired ");
  328.     }
  329.     tprintf("SRTT %ld ms Mean dev %ld ms\n",tcb->srtt,tcb->mdev);
  330. }
  331.  
  332. /* tcp timers type - linear v exponential */
  333. static dotcptimer(argc,argv,p)
  334. int argc ;
  335. char *argv[] ;
  336. void *p ;
  337. {
  338.     extern int tcptimertype;
  339.  
  340.     if (argc < 2) {
  341.         tprintf("Tcp timer type is %s\n", tcptimertype ? "linear" : "exponential" ) ;
  342.         return 0 ;
  343.     }
  344.     
  345.     switch (argv[1][0]) {
  346.         case 'l':
  347.         case 'L':
  348.             tcptimertype = 1 ;
  349.             break ;
  350.         case 'e':
  351.         case 'E':
  352.             tcptimertype = 0 ;
  353.             break ;
  354.         default:
  355.             tprintf("use: tcp timertype [linear|exponential]\n") ;
  356.             return -1 ;
  357.     }
  358.  
  359.     return 0 ;
  360. }
  361.  
  362.